package com.shigen.demo.ForkJoinDemo;

/**
 * @author shigenfu
 * @date 2024/4/9 11:16
 */

import cn.hutool.core.date.StopWatch;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class SumCalculator extends RecursiveTask<Long> {

    private static final long serialVersionUID = 1L;
    // 阈值，超过这个值则拆分任务
    private static final long THRESHOLD = 10000;
    private final long start;
    private final long end;

    public SumCalculator(long start, long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        long length = end - start;
        if (length <= THRESHOLD) {
            return computeSequentially();
        }
        long middle = (start + end) >>> 1;
        SumCalculator leftTask = new SumCalculator(start, middle);
        SumCalculator rightTask = new SumCalculator(middle + 1, end);
        // 拆分左边任务
        leftTask.fork();
        // 拆分右边任务
        rightTask.fork();
        // 合并并返回结果
        return leftTask.join() + rightTask.join();
    }

    private long computeSequentially() {
        long sum = 0;
        for (long i = start; i <= end; i++) {
            sum += i;
        }
        return sum;
    }

    public static void main(String[] args) {
        long start = 1;
        long end = 1_0000_0000;
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        long result = forkJoinPool.invoke(new SumCalculator(start, end));
        stopWatch.stop();
        System.out.println("Sum of " + start + " to " + end + " = " + result);
        System.out.println("Elapsed time: " + stopWatch.getTotalTimeMillis() + " ms");
    }
}

